#include "basic_at.h"

char wifiATCmdString[WIFI_AT_CMD_MAX_LEN]; // AT指令字符串

// AT+GSLP=<time>
void moduleGSleep(char *sleepTime)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_GSLP, sizeof(WIFI_AT_GSLP));
    strcat(wifiATCmdString, sleepTime); // AT+GSLP=<time>
    strcat(wifiATCmdString, "\r\n");
}

/*
*查询指令: AT+UART_CUR?(AT+UART_DEF?)
*设置指令:
*AT+UART_CUR=<baudrate>,<databits>,<stopbits>,<parity>,<flow control>
• <baudrate>：UART 波特率
• <databits>：数据位
‣ 5：5 bit 数据位
‣ 6：6 bit 数据位
‣ 7：7 bit 数据位
‣ 8：8 bit 数据位
• <stopbits>：停⽌止位
‣ 1：1 bit 停⽌止位
‣ 2：1.5 bit 停⽌止位
‣ 3：2 bit 停⽌止位
• <parity>：校验位
‣ 0：None
‣ 1：Odd
‣ 2：Even
• <flow control>：流控
‣ 0：不不使能流控
‣ 1：使能 RTS
‣ 2：使能 CTS
‣ 3：同时使能 RTS 和 CTS
*(示例:AT+UART_CUR=115200,8,1,0,3;AT+UART_DEF=115200,8,1,0,3)
*cmdType:0表示查询，1表示设置
*saveType:0表示不写入Flash,1表示写入Flash
*/
void moduleUARTSet(char *baudRate, char *dataBits, char *stopBits, char *parity, char *flowControl, uint8_t cmdType, uint8_t saveType)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    // 保存类型
    if (saveType)
    {
        memcpy(wifiATCmdString, WIFI_AT_UART_DEF, sizeof(WIFI_AT_UART_DEF));
    }
    else
    {
        memcpy(wifiATCmdString, WIFI_AT_UART_CUR, sizeof(WIFI_AT_UART_CUR));
    }
    // 命令类型
    if (cmdType)
    {
        // 设置参数
        strcat(wifiATCmdString, "=");
        strcat(wifiATCmdString, baudRate);
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, dataBits);
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, stopBits);
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, parity);
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, flowControl);
    }
    else
    {
        // 查询参数
        strcat(wifiATCmdString, "?");
    }
    strcat(wifiATCmdString, "\r\n");
}

/*
**cmdType:0表示查询，1表示设置
*查询指令:AT+SLEEP?
*设置指令:AT+SLEEP=<sleep mode>,返回OK或ERROR
<sleep mode>:
‣ 0：禁⽤用休眠模式
‣ 1：Light-sleep 模式
‣ 2：Modem-sleep 模式
Sleep模式仅在单Station模式下⽣效,默认为Modem-sleep模式
示例:AT+SLEEP=0
*/
void moduleSleep(char *sleepTime, uint8_t cmdType)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_SLEEP, sizeof(WIFI_AT_SLEEP));
    if (cmdType)
    {
        strcat(wifiATCmdString, "=");
        strcat(wifiATCmdString, sleepTime);
    }
    else
    {
        strcat(wifiATCmdString, "?");
    }
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+WAKEUPGPIO-设置GPIO唤醒Light-sleep模式
*AT+WAKEUPGPIO=<enable>,<trigger_GPIO>,<trigger_level>[,<awake_GPIO>,<awake_level>]
• <enable>
‣ 0：禁⽤用 GPIO 唤醒 Light-sleep 功能
‣ 1：使能 GPIO 唤醒 Light-sleep 功能
• <trigger_GPIO>
‣ 设置⽤用于唤醒 Light-sleep 的 GPIO，有效范围：[0, 15]
• <trigger_level>
‣ 0：低电平唤醒
‣ 1：⾼高电平唤醒
• [<awake_GPIO>]
‣ 选填参数，设置 Light-sleep 唤醒后的标志 GPIO，有效范围：[0, 15]
• [<awake_level>]
‣ 选填参数
‣ 0：Light-sleep 唤醒后置为低电平
‣ 1：Light-sleep 唤醒后置为⾼高电平
• Light sleep 唤醒过程约 5 ms，请等待⾄至少 5ms 后再发送 AT 指令。
• <trigger_GPIO> 与 <awake_GPIO> 不不能相同
• 由 <trigger_GPIO> 触发 ESP8266 从 Light-sleep 唤醒之后，如需再次进⼊入休眠时，ESP8266 将判断 <trigger_GPIO> 的状态：
‣ 如果 <trigger_GPIO> 仍然处于唤醒状态，则进⼊入 Modem-sleep 休眠；
‣ 如果 <trigger_GPIO> 不不处于唤醒状态，则进⼊入 Light-sleep 休眠。
示例：
• 设置 GPIO0 低电平唤醒 Light-sleep 模式：
AT+WAKEUPGPIO=1,0,0
• 设置 GPIO0 ⾼高电平唤醒 Light-sleep 模式，唤醒后，将 GPIO13 设置为⾼高电平：
AT+WAKEUPGPIO=1,0,1,13,1
• 取消 GPIO 唤醒 Light-sleep 模式的功能：
AT+WAKEUPGPIO=0
*/
void moduleWAKEUPGPIO(char *enable, char *trigger_GPIO, char *trigger_level, char *awake_GPIO, char *awake_level)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    uint8_t enableNum = 0;
    memcpy(wifiATCmdString, WIFI_AT_WAKE_UP_GPIO, sizeof(WIFI_AT_WAKE_UP_GPIO));
    if (enable != NULL)
    {
        enableNum = atoi(enable);
    }
    strcat(wifiATCmdString, enable);
    if (enableNum)
    {
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, trigger_GPIO);
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, trigger_level);
        if (awake_GPIO != NULL)
        {
            strcat(wifiATCmdString, ",");
            strcat(wifiATCmdString, awake_GPIO);
            strcat(wifiATCmdString, ",");
            strcat(wifiATCmdString, awake_level);
        }
    }
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+RFPOWER一设置 RF TX Power 上限
*AT+RFPOWER=<tx_power>
<TX Power>：RF TX Power 值，参数范围：[0, 82]，单位：0.25 dBm
示例:AT+RFPOWER=50
*/
void moduleRFPOWER(char *tx_power)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_RF_POWER, sizeof(WIFI_AT_RF_POWER));
    strcat(wifiATCmdString, tx_power);
    strcat(wifiATCmdString, "\r\n");
}

/*
 *AT+RFVDD-根据 VDD33 设置 RF TX Power
 *查询命令:
 *AT+RFVDD?
 *响应:+RFVOD:<VDD33>
 *<VDD33>:VDD33 电压值，单位：1/1024 V
 *本查询指令必须在 TOUT管脚悬空的情况下使⽤用，否则，查询返回⽆无效值
 *设置命令:
 *AT+RFVDD=<vdd33>
 *<vdd33>：VDD33 电压值，取值范围：[1900, 3300]
 *执行命令：
 *AT+RFVDD
 *功能：ESP8266 ⾃自动根据实际的VDD33调整RF TX Power
 *本查询指令必须在 TOUT 管脚悬空的情况下使⽤
 *cmdType:0表示查询，1表示设置，2表示执行
 */
void moduleRFVDD(char *vdd33, uint8_t cmdType)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_RF_VDD, sizeof(WIFI_AT_RF_VDD));
    switch (cmdType)
    {
    case 0: // 查询
    {
        strcat(wifiATCmdString, "?");
    }
    break;
    case 1: // 设置
    {
        strcat(wifiATCmdString, "=");
        strcat(wifiATCmdString, vdd33);
    }
    break;
    case 2: // 执行
        break;
    default:
        break;
    }
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+SYSRAM一查询系统当前剩余内存:
*AT+SYSRAM?
*响应:
+SYSRAM:<RAM>
OK
*<RAM>：系统当前剩余内存，单位：byte
*
*AT+SYSADC-查询 ADC 值：
*AT+SYSADC?
*响应:
+SYSADC:<ADC>
OK
*<ADC>：查询到的 ADC 值，单位：1/1024V
*/

/*
*AT+SYSIOSETCFG一设置IO工作模式
*AT+SYSIOSETCFG=<pin>,<mode>,<pull-up>
• <pin>：IO 管脚号
• <mode>：IO ⼯工作模式
• <pull-up>
‣ 0：不不使能上拉
‣ 1：使能上拉
*示例：AT+SYSIOSETCFG=12,3,1 //设置 GPIO12 工作为 GPIO 模式
*/
void moduleSYSIOCFG(char *pin, char *mode, char *pull_up)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_SYS_IO_SET_CFG, sizeof(WIFI_AT_SYS_IO_SET_CFG));
    strcat(wifiATCmdString, pin);
    strcat(wifiATCmdString, ",");
    strcat(wifiATCmdString, mode);
    strcat(wifiATCmdString, ",");
    strcat(wifiATCmdString, pull_up);
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+SYSIOGETCFG-查询IO工作模式
*AT+SYSIOGETCFG=<pin>
• <pin>：IO 管脚号
• <mode>：IO ⼯工作模式
• <pull-up>
‣ 0：不不使能上拉
‣ 1：使能上拉
*/
void moduleSYSIOGETCFG(char *pin)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_SYS_IO_GET_CFG, sizeof(WIFI_AT_SYS_IO_GET_CFG));
    strcat(wifiATCmdString, pin);
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+SYSGPIODIR一设置 GPIO 工作为输入或输出
*AT+SYSGPIODIR=<pin>,<dir>
• <pin>：GPIO 号
• <dir>：
‣ 0：设置 GPIO 为输⼊入
‣ 1：设置 GPIO 为输出
*示例：
AT+SYSIOSETCFG=12,3,1 //设置 GPIO12 工作为 GPIO 模式
AT+SYSGPIODIR=12,0 //设置 GPIO12 为输入
*/
void moduleSYSGPIODIR(char *pin, char *dir)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    memcpy(wifiATCmdString, WIFI_AT_SYS_GPIO_DIR, sizeof(WIFI_AT_SYS_GPIO_DIR));
    strcat(wifiATCmdString, pin);
    strcat(wifiATCmdString, ",");
    strcat(wifiATCmdString, dir);
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+SYSGPIOWRITE一设置 GPIO 的输出电平
*AT+SYSGPIOWRITE=<pin>,<level>
• 如果成功，提示
OK
• 如果 IO 管脚不不处于输出模式，则提示
NOT OUTPUT！
ERROR
*参数说明：
• <pin>：GPIO 号
• <level>：
‣ 0：低电平
‣ 1：⾼高电平
*示例：
AT+SYSIOSETCFG=12,3,1 //设置 GPIO12 工作为 GPIO 模式
AT+SYSGPIODIR=12,1 //设置 GPIO12 为输出
AT+SYSGPIOWRITE=12,1 //设置 GPIO12 输出高电平
*
*AT+SYSGPIOREAD一读取 GPI0 的电平状态
*AT+SYSGPIOREAD=<pin>
• 如果成功，返回
+SYSGPIOREAD:<pin>,<dir>,<level>
OK
• 如果 IO 管脚不不处于输出模式，则提示
NOT GPIO MODE！
ERROR
*参数说明：
• <pin>：GPIO 号
• <dir>：
‣ 0：设置 GPIO 为输⼊入
‣ 1：设置 GPIO 为输出
• <level>：
‣ 0：低电平
‣ 1：⾼高电平
*示例：
AT+SYSIOSETCFG=12,3,1 //设置 GPIO12 工作为 GPIO 模式
AT+SYSGPIODIR=12,0 //设置 GPIO12 为输入
AT+SYSGPIOREAD=12
*cmdType:0表示读取，1表示写入
*/
void moduleSYSGPIOWR(char *pin, char *level, uint8_t cmdType)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    if (cmdType)
    {
        memcpy(wifiATCmdString, WIFI_AT_SYS_GPIO_WRITE, sizeof(WIFI_AT_SYS_GPIO_WRITE));
        strcat(wifiATCmdString, pin);
        strcat(wifiATCmdString, ",");
        strcat(wifiATCmdString, level);
    }
    else
    {
        memcpy(wifiATCmdString, WIFI_AT_SYS_GPIO_READ, sizeof(WIFI_AT_SYS_GPIO_READ));
        strcat(wifiATCmdString, pin);
    }
    strcat(wifiATCmdString, "\r\n");
}

/*
*AT+SYSMSG_CUR—设置当前系统消息，不不保存到 flash
*AT+SYSMSG_CUR=<n>
<n>：
• bit0：控制退出透传的消息
‣ 若 bit0 为 0，退出透传时，⽆无提示消息；默认为 0
‣ 若 bit0 为 1，退出透传时，提示消息 +QUITT // Quit transparent transmission
• bit1：控制建⽴立⽹网络连接的消息
‣ 若 bit1 为 0，⽹网络连接建⽴立时，提示消息 <Link_ID>,CONNECT；默认为 0
‣ 若 bit1 为 1，⽹网络连接建⽴立时，提示消息 +LINK_CONN:<status_type>,<link_id>,"UDP/TCP/SSL",<c/s>,<remote_ip>,<remote_port>,<local_port>；
- <status_type> 为 0 表示连接成功，为 1 表示连接失败；
- <c/s> 为 0 表示 ESP 作为 client，为 1 表示 ESP 作为 server。
本设置不不保存到 flash 中，重新上电后失效。
*示例：
AT+SYSMSG_CUR=3
*
*AT+SYSMSG DEF一设置默认系统消息，保存到 flash
*AT+SYSMSG_DEF=<n>
<n>：
• bit0：控制退出透传的消息
‣ 若 bit0 为 0，退出透传时，⽆无提示消息；默认为 0
‣ 若 bit0 为 1，退出透传时，提示消息 +QUITT // Quit transparent transmission
• bit1：控制建⽴立⽹网络连接的消息
‣ 若 bit1 为 0，⽹网络连接建⽴立时，提示消息 <Link_ID>, CONNECT；默认为 0
‣ 若 bit1 为 1，⽹网络连接建⽴立时，提示消息 +LINK_CONN:<status_type>,<link_id>,"UDP/
TCP/SSL",<c/s>,<remote_ip>,<remote_port>,<local_port>；
- <status_type> 为 0 表示连接成功，为 1 表示连接失败；
- <c/s> 为 0 表示 ESP 作为 client，为 1 表示 ESP 作为 server。
本设置保存到 flash 中，重新上电后仍然有效。
*示例：
AT+SYSMSG_DEF=3
*
*cmdType:0表示不写入Flash，1表示写入Flash
*/
void moduleSYSMSG_CUR_DEF(char *n, uint8_t cmdType)
{
    memset(wifiATCmdString, 0, WIFI_AT_CMD_MAX_LEN); // 清空指令字符串
    if (cmdType)
    {
        memcpy(wifiATCmdString, WIFI_AT_SYS_MSG_DEF, sizeof(WIFI_AT_SYS_MSG_DEF));
        strcat(wifiATCmdString, n);
    }
    else
    {
        memcpy(wifiATCmdString, WIFI_AT_SYS_MSG_CUR, sizeof(WIFI_AT_SYS_MSG_CUR));
        strcat(wifiATCmdString, n);
    }
    strcat(wifiATCmdString, "\r\n");
}
